package org.idtem.component.algoritmo.engine.utilidades;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import org.apache.uima.cas.FSIterator;
import org.apache.uima.cas.FSTypeConstraint;
import org.apache.uima.cas.Type;
import org.apache.uima.jcas.JCas;
import org.idtem.component.algoritmo.InfoDoc;
import org.idtem.component.algoritmo.Resultado;
import org.idtem.component.algoritmo.Resultado1;
import org.idtem.component.algoritmo.Resultado2;
import org.idtem.component.algoritmo.Resultado3;
import org.idtem.component.algoritmo.SentenciaCompletitud;
import org.idtem.component.common.Frase;
import org.idtem.component.common.FreelingConsulta;
import org.idtem.component.freeling.Adjetivo;
import org.idtem.component.freeling.Adverbio;
import org.idtem.component.freeling.Freeling2;
import org.idtem.component.freeling.Nombre;
import org.idtem.component.freeling.Pronombre;
import org.idtem.component.freeling.Sentencia;
import org.idtem.component.freeling.Verbo;
import org.idtem.component.identificador.BeInStateInverseRelation;
import org.idtem.component.identificador.BeInStateRelation;
import org.idtem.component.identificador.CausesInverseRelation;
import org.idtem.component.identificador.CausesRelation;
import org.idtem.component.identificador.DataRelacion;
import org.idtem.component.identificador.HasDerivedInverseRelation;
import org.idtem.component.identificador.HasDerivedRelation;
import org.idtem.component.identificador.HasHoloMadeofInverseRelation;
import org.idtem.component.identificador.HasHoloMadeofRelation;
import org.idtem.component.identificador.HasHoloMemberInverseRelation;
import org.idtem.component.identificador.HasHoloMemberRelation;
import org.idtem.component.identificador.HasHoloPartInverseRelation;
import org.idtem.component.identificador.HasHoloPartRelation;
import org.idtem.component.identificador.HasHyponymInverseRelation;
import org.idtem.component.identificador.HasHyponymRelation;
import org.idtem.component.identificador.HasMeroMemberInverseRelation;
import org.idtem.component.identificador.HasMeroMemberRelation;
import org.idtem.component.identificador.HasMeroPartInverseRelation;
import org.idtem.component.identificador.HasMeroPartRelation;
import org.idtem.component.identificador.HasSubeventInverseRelation;
import org.idtem.component.identificador.HasSubeventRelation;
import org.idtem.component.identificador.HasXposHyponymInverseRelation;
import org.idtem.component.identificador.HasXposHyponymRelation;
import org.idtem.component.identificador.LemaRelation;
import org.idtem.component.identificador.NearAntonymRelation;
import org.idtem.component.identificador.NearSynonymRelation;
import org.idtem.component.identificador.PertainsToRelation;
import org.idtem.component.identificador.RoleAgentInverseRelation;
import org.idtem.component.identificador.RoleAgentRelation;
import org.idtem.component.identificador.RoleInstrumentInverseRelation;
import org.idtem.component.identificador.RoleInstrumentRelation;
import org.idtem.component.identificador.RoleLocationInverseRelation;
import org.idtem.component.identificador.RoleLocationRelation;
import org.idtem.component.identificador.RolePatientInverseRelation;
import org.idtem.component.identificador.RolePatientRelation;
import org.idtem.component.identificador.RoleRelation;
import org.idtem.component.identificador.SinonimoRelation;
import org.idtem.component.identificador.XposNearSynonymInverseRelation;
import org.idtem.component.identificador.XposNearSynonymRelation;
import org.idtem.utils.constants.Constants;
import org.idtem.utils.eagles.EAGLESHelper;
import org.idtem.utils.eagles.StopList;

public class UtilidadesDeAnalisis {

	public static class SentenciaUtils
	{
	
		public static int cantTotalSentencias(JCas cas)
		{
			return getSentencias(cas).size();
		}
		
		public static int cantNombresSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			return getNombresSentencia(sentencia, withOffset, cas).size();
		}
		
		public static int cantVerbosSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			return getVerbosSentencia(sentencia, withOffset, cas).size();
		}
		
		public static int cantAdverbiosSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			return getAdverbiosSentencia(sentencia, withOffset, cas).size();
		}
		
		public static int cantAdjetivosSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			return getAdjetivosSentencia(sentencia, withOffset, cas).size();
		}
		
		public static int cantPalabrasSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			return getPalabrasSentencia(sentencia, withOffset, cas).size();
		}

		public static SentenciaCompletitud getSentenciaCompletitud(Sentencia sentencia, JCas cas)
		{
			FSIterator it = getSentenciaCompletitudIterator(cas);
			while (it.hasNext())
			{
				SentenciaCompletitud sentenciaComp = (SentenciaCompletitud) it.next();
				if (sentencia.getBegin() == sentenciaComp.getBegin())
					return sentenciaComp;
			}
			try {
				throw new Exception();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
					
		}

		public static int cantOffsetsSentencia(Sentencia sentencia, JCas cas) {
			Collection<Freeling2> wnFreeling2ArrayList = getWNPOSSentencia(sentencia, true, cas);
			int cantOffsets = 0;
			for (Freeling2 freeling2 : wnFreeling2ArrayList) {
				cantOffsets += freeling2.getOffsets().size();
			}
			return cantOffsets;
		}
		
		public static Collection<Freeling2> getWNPOSSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			FSIterator freeling2Iterator = getWNPOSSIterator(cas);
			ArrayList<Freeling2> result = new ArrayList<Freeling2>();
			while (freeling2Iterator.hasNext())
			{
				Freeling2 freeling2 = (Freeling2) freeling2Iterator.next();
				if (freeling2.getBegin() > sentencia.getEnd())
					return result;
				if (freeling2.getBegin() >= sentencia.getBegin() && freeling2.getEnd() <= sentencia.getEnd())
				{
					if (!withOffset || freeling2.getOffsets().size() > 0)
						result.add(freeling2);
				}
			}
			return result;
		
		}

		public static Collection<Nombre> getNombresSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			FSIterator nombreIterator = getNombreIterator(cas);
			ArrayList<Nombre> result = new ArrayList<Nombre>();
			while (nombreIterator.hasNext())
			{
				Nombre nombre = (Nombre) nombreIterator.next();
				if (nombre.getBegin() > sentencia.getEnd())
					return result;
				if (nombre.getBegin() >= sentencia.getBegin() && nombre.getEnd() <= sentencia.getEnd())
				{
					if (!withOffset || nombre.getOffsets().size() >0)
						result.add(nombre);
				}
			}
			return result;
		}
		
		public static Collection<Pronombre> getPronombresSentencia(Sentencia sentencia, JCas cas)
		{
			FSIterator pronombreIterator = getPronombreIterator(cas);
			ArrayList<Pronombre> result = new ArrayList<Pronombre>();
			while (pronombreIterator.hasNext())
			{
				Pronombre pronombre = (Pronombre) pronombreIterator.next();
				if (pronombre.getBegin() > sentencia.getEnd())
					return result;
				if (pronombre.getBegin() >= sentencia.getBegin() && pronombre.getEnd() <= sentencia.getEnd())
				{
					result.add(pronombre);
				}
			}
			return result;
		}
		
		public static Collection<Verbo> getVerbosSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			FSIterator verboIterator = getVerboIterator(cas);
			ArrayList<Verbo> result = new ArrayList<Verbo>();
			while (verboIterator.hasNext())
			{
				Verbo verbo = (Verbo) verboIterator.next();
				if (verbo.getBegin() > sentencia.getEnd())
					return result;
				if (verbo.getBegin() >= sentencia.getBegin() && verbo.getEnd() <= sentencia.getEnd())
				{
					if (!withOffset || verbo.getOffsets().size() >0)
						result.add(verbo);
				}
			}
			return result;
		}
		
		public static Collection<Adverbio> getAdverbiosSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			FSIterator adverbioIterator = getAdverbioIterator(cas);
			ArrayList<Adverbio> result = new ArrayList<Adverbio>();
			while (adverbioIterator.hasNext())
			{
				Adverbio advervio = (Adverbio) adverbioIterator.next();
				if (advervio.getBegin() > sentencia.getEnd())
					return result;
				if (advervio.getBegin() >= sentencia.getBegin() && advervio.getEnd() <= sentencia.getEnd())
				{
					if (!withOffset || advervio.getOffsets().size() >0)
						result.add(advervio);
				}
			}
			return result;
		}
		
		public static Collection<Adjetivo> getAdjetivosSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			FSIterator adjetivoIterator = getAdjetivoIterator(cas);
			ArrayList<Adjetivo> result = new ArrayList<Adjetivo>();
			while (adjetivoIterator.hasNext())
			{
				Adjetivo adjetivo = (Adjetivo) adjetivoIterator.next();
				if (adjetivo.getBegin() > sentencia.getEnd())
					return result;
				if (adjetivo.getBegin() >= sentencia.getBegin() && adjetivo.getEnd() <= sentencia.getEnd())
				{
					if (!withOffset || adjetivo.getOffsets().size() >0)
						result.add(adjetivo);
				}
			}
			return result;
		}
		
		public static Collection<Freeling2> getPalabrasSentencia(Sentencia sentencia, boolean withOffset, JCas cas)
		{
			FSIterator freeling2Iterator = getFreeling2Iterator(cas);
			ArrayList<Freeling2> result = new ArrayList<Freeling2>();
			while (freeling2Iterator.hasNext())
			{
				Freeling2 freeling2 = (Freeling2) freeling2Iterator.next();
				if (freeling2.getBegin() > sentencia.getEnd())
					return result;
				if (EAGLESHelper.isSignosDePuntuacion(freeling2.getEagles()))
					continue;
				if (freeling2.getBegin() >= sentencia.getBegin() && freeling2.getEnd() <= sentencia.getEnd())
				{
					if (!withOffset || freeling2.getOffsets().size() >0)
						result.add(freeling2);
				}
			}
			return result;
		}

	}
	
	public static FSIterator getRelationIterator(JCas cas){
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new DataRelacion(cas)).getType());
		return cas.createFilteredIterator(it, constraint);
	}
	
	public static Collection<DataRelacion> getRelationAnnotations(JCas cas){
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new DataRelacion(cas)).getType());
		it = cas.createFilteredIterator(it, constraint);
		ArrayList<DataRelacion> result = new ArrayList<DataRelacion>();
		while (it.hasNext())
		{
			result.add((DataRelacion) it.next());
		}
		return result;
	}
	
	public static FSIterator getFreelingConsultaIterator(JCas cas){
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new FreelingConsulta(cas)).getType());
		return cas.createFilteredIterator(it, constraint);
	}
	
	public static Collection<FreelingConsulta> getFreelingConsultaAnnotators(JCas cas) {
		FSIterator it = getFreelingConsultaIterator(cas);
		ArrayList<FreelingConsulta> result = new ArrayList<FreelingConsulta>();
		while (it.hasNext())
		{
			result.add((FreelingConsulta) it.next());
		}
		return result;
	}
	
	public static Collection<Sentencia> getSentencias(JCas cas) {
		Collection<Sentencia> sentencias = new ArrayList<Sentencia>();
		FSIterator it = getSentenciaIterator(cas);
		while (it.hasNext())
		{
			Sentencia sentencia = (Sentencia)it.next();
			sentencias.add(sentencia);
		}
		return sentencias;
	}
	
	public static Frase getFrase(JCas cas) {
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new Frase(cas)).getType());
		it = cas.createFilteredIterator(it, constraint);
		if (it.hasNext())
		{
			return (Frase)it.next();
		}
		try {
			throw new Exception();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public static int getRelationWeight(DataRelacion annotation) 
	{
		if (annotation instanceof LemaRelation){
			return Constants.AlgoritmosConstants.PESO_LEMAS;
		}
		
		if (annotation instanceof SinonimoRelation){
			return Constants.AlgoritmosConstants.PESO_SINONIMOS;
		}
		
		if (annotation instanceof HasHyponymInverseRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_HYPONYM_INVERSE;
		}
		
		if (annotation instanceof HasHyponymRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_HYPONYM;
		}

		//#Ponderaciones - Relaciones Directas
		 
		if (annotation instanceof NearSynonymRelation){
			return Constants.AlgoritmosConstants.PESO_NEAR_SYNONYM;
		}
		 
		if (annotation instanceof HasDerivedRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_DERIVED;
		}
		 
		if (annotation instanceof HasHoloPartRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_HOLO_PART;
		}
		 
		if (annotation instanceof HasHoloMadeofRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_HOLO_MADEOF;
		}
		
		if (annotation instanceof HasHoloMemberRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_HOLO_MEMBER;
		}
		
		if (annotation instanceof NearAntonymRelation){
			return Constants.AlgoritmosConstants.PESO_NEAR_ANTONYM;
		}
		
		if (annotation instanceof BeInStateRelation){
			return Constants.AlgoritmosConstants.PESO_BE_IN_STATE;
		}
		
		if (annotation instanceof RoleAgentRelation){
			return Constants.AlgoritmosConstants.PESO_ROLE_AGENT;
		}
		
		if (annotation instanceof HasXposHyponymRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_XPOS_HYPONYM;
		}
		
		if (annotation instanceof HasSubeventRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_SUBEVENT;
		}
		
		if (annotation instanceof XposNearSynonymRelation){
			return Constants.AlgoritmosConstants.PESO_XPOS_NEAR_SYNONYM;
		}
		
		if (annotation instanceof HasMeroMemberRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_MERO_MEMBER;
		}
		
		if (annotation instanceof CausesRelation){
			return Constants.AlgoritmosConstants.PESO_CAUSES;
		}
		
		if (annotation instanceof HasMeroPartRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_MERO_PART;
		}
		
		if (annotation instanceof PertainsToRelation){
			return Constants.AlgoritmosConstants.PESO_PERTAINS_TO;
		}
		
		if (annotation instanceof RoleRelation){
			return Constants.AlgoritmosConstants.PESO_ROLE;
		}
		
		if (annotation instanceof RoleInstrumentRelation){
			return Constants.AlgoritmosConstants.PESO_ROLE_INSTRUMENT;
		}
		
		if (annotation instanceof RoleLocationRelation){
			return Constants.AlgoritmosConstants.PESO_ROLE_LOCATION;
		}
		
		if (annotation instanceof RolePatientRelation){
			return Constants.AlgoritmosConstants.PESO_ROLE_PATIENT;
		}

		//#Ponderaciones - Relaciones Inversas
				
		if (annotation instanceof HasXposHyponymInverseRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_XPOS_HYPONYM_INVERSE;
		}
		
		if (annotation instanceof HasMeroPartInverseRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_MERO_PART_INVERSE;
		}
		
		if (annotation instanceof XposNearSynonymInverseRelation){
			return Constants.AlgoritmosConstants.PESO_XPOS_NEAR_SYNONYM_INVERSE;
		}
		
		if (annotation instanceof HasMeroMemberInverseRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_MERO_MEMBER_INVERSE;
		}
		
		
		if (annotation instanceof CausesInverseRelation){
			return Constants.AlgoritmosConstants.PESO_CAUSES_INVERSE;
		}
		
		if (annotation instanceof HasDerivedInverseRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_DERIVED_INVERSE;
		}
		
		if (annotation instanceof HasHoloPartInverseRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_HOLO_PART_INVERSE;
		}
		
		if (annotation instanceof HasHoloMadeofInverseRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_HOLO_MADEOF_INVERSE;
		}
		
		if (annotation instanceof HasHoloMemberInverseRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_HOLO_MEMBER_INVERSE;
		}
		
		if (annotation instanceof BeInStateInverseRelation){
			return Constants.AlgoritmosConstants.PESO_BE_IN_STATE_INVERSE;
		}
		
		if (annotation instanceof RoleAgentInverseRelation){
			return Constants.AlgoritmosConstants.PESO_ROLE_AGENT_INVERSE;
		}
		
		if (annotation instanceof HasSubeventInverseRelation){
			return Constants.AlgoritmosConstants.PESO_HAS_SUBEVENT_INVERSE;
		}
		
		if (annotation instanceof RoleLocationInverseRelation){
			return Constants.AlgoritmosConstants.PESO_ROLE_LOCATION_INVERSE;
		}
		
		if (annotation instanceof RoleInstrumentInverseRelation){
			return Constants.AlgoritmosConstants.PESO_ROLE_INSTRUMENT_INVERSE;
		}

		if (annotation instanceof RolePatientInverseRelation){
			return Constants.AlgoritmosConstants.PESO_ROLE_PATIENT_INVERSE;
		}
		
		try {
			throw new Exception();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return 0;
	}
	
	public static FSIterator getNombreIterator(JCas cas)
	{
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new Nombre(cas)).getType());
		return cas.createFilteredIterator(it, constraint);
	}
	
	private static FSIterator getVerboIterator(JCas cas) {
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new Verbo(cas)).getType());
		return cas.createFilteredIterator(it, constraint);
	}
	
	private static FSIterator getAdverbioIterator(JCas cas) {
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new Adverbio(cas)).getType());
		return cas.createFilteredIterator(it, constraint);
	}
	
	private static FSIterator getAdjetivoIterator(JCas cas) {
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new Adjetivo(cas)).getType());
		return cas.createFilteredIterator(it, constraint);
	}
	
	private static FSIterator getPronombreIterator(JCas cas) {
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new Pronombre(cas)).getType());
		return cas.createFilteredIterator(it, constraint);
	}
	
	private static FSIterator getWNPOSSIterator(JCas cas)
	{
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new Adjetivo(cas)).getType());
		constraint.add((new Adverbio(cas)).getType());
		constraint.add((new Verbo(cas)).getType());
		constraint.add((new Nombre(cas)).getType());
		return cas.createFilteredIterator(it, constraint);
		
	}
	
	public static FSIterator getSentenciaIterator(JCas cas) {
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new Sentencia(cas)).getType());
		return cas.createFilteredIterator(it, constraint);
	}

	public static DataInfoDocumento obtenerInfoDocumento(JCas cas) {
		DataInfoDocumento result = new DataInfoDocumento();
		Collection<Sentencia> sentencias = getSentencias(cas);
		
		int cantSentenciasConOffset = 0;
		int cantPalabrasConOffset = 0;
		int cantOffset = 0;

		
		for (Sentencia sentencia : sentencias) {
			Collection<Freeling2> freelingWN = SentenciaUtils.getWNPOSSentencia(sentencia, false, cas);
			boolean sentenciaConOffset = false;
			for (Freeling2 freeling2 : freelingWN) {
				if (freeling2.getOffsets().size() > 0)
				{
					cantPalabrasConOffset++;
					cantOffset += freeling2.getOffsets().size();
					sentenciaConOffset = true;
				}
			}
			if (sentenciaConOffset)
				cantSentenciasConOffset++;
		}
		result.setCantSentencias(sentencias.size());
		result.setCantSentenciasConOffset(cantSentenciasConOffset);
		result.setCantOffset(cantOffset);
		result.setCantPalabrasConOffset(cantPalabrasConOffset);
		
		
		int cantPalabras = 0;
		Collection<Freeling2> freeling2Collection = UtilidadesDeAnalisis.getFreeling2Annotations(cas);
		for (Freeling2 freeling2 : freeling2Collection) {
			if (!EAGLESHelper.isSignosDePuntuacion(freeling2.getEagles()))
				cantPalabras++;
		}
		result.setCantPalabras(cantPalabras);
		
		// Tokens Consulta
		Collection<FreelingConsulta> freelingConsultaAnnotations = UtilidadesDeAnalisis.getFreelingConsultaAnnotators(cas);
		int totalTokensConsulta = freelingConsultaAnnotations.size();
		int cantTokensConsultaNoFiltered = totalTokensConsulta;
		int cantOffsetFraseConsulta = 0;
		
		int cantNombresConsulta = 0;
		int cantVerbosConsulta = 0;
		int cantAdjetivosConsulta = 0;
		int cantAdverbiosConsulta = 0;
		int cantNombresConsultaConOffset = 0;
		int cantVerbosConsultaConOffset = 0;
		int cantAdjetivosConsultaConOffset = 0;
		int cantAdverbiosConsultaConOffset = 0;
		
		
		
		for (FreelingConsulta freelingConsulta : freelingConsultaAnnotations) {
			if (EAGLESHelper.isNombre(freelingConsulta.getEagles()))
			{
				cantNombresConsulta++;
				if (freelingConsulta.getOffsets().size() > 0)
				{
					cantNombresConsultaConOffset++;
					cantOffsetFraseConsulta += freelingConsulta.getOffsets().size();
				}
			}
			else if (EAGLESHelper.isVerbo(freelingConsulta.getEagles()))
			{
				cantVerbosConsulta++;
				if (freelingConsulta.getOffsets().size() > 0)
				{
					cantVerbosConsultaConOffset++;
					cantOffsetFraseConsulta += freelingConsulta.getOffsets().size();
				}
			}
			else if (EAGLESHelper.isAdjetivo(freelingConsulta.getEagles()))
			{
				cantAdjetivosConsulta++;
				if (freelingConsulta.getOffsets().size() > 0)
				{
					cantAdjetivosConsultaConOffset++;
					cantOffsetFraseConsulta += freelingConsulta.getOffsets().size();
				}
			}
			else if (EAGLESHelper.isAdverbio(freelingConsulta.getEagles()))
			{
				cantAdjetivosConsulta++;
				if (freelingConsulta.getOffsets().size() > 0)
				{
					cantAdjetivosConsultaConOffset++;
					cantOffsetFraseConsulta += freelingConsulta.getOffsets().size();
				}
			}
			if (StopList.isFilteredByStopList(freelingConsulta.getEagles()))
				cantTokensConsultaNoFiltered--;
		}
		
		
		result.setCantTokensConsulta(totalTokensConsulta);
		result.setCantTokensConsultaNoFiltered(cantTokensConsultaNoFiltered);
		result.setCantOffsetsFraseConsulta(cantOffsetFraseConsulta);
		
		
		result.setCantNombresConsulta(cantNombresConsulta);
		result.setCantVerbosConsulta(cantVerbosConsulta);
		result.setCantAdjetivosConsulta(cantAdjetivosConsulta);
		result.setCantAdverbiosConsulta(cantAdverbiosConsulta);
		result.setCantNombresConsultaConOffset(cantNombresConsultaConOffset);
		result.setCantVerbosConsultaConOffset(cantVerbosConsultaConOffset);
		result.setCantAdjetivosConsultaConOffset(cantAdjetivosConsultaConOffset);
		result.setCantAdverbiosConsultaConOffset(cantAdverbiosConsultaConOffset);
		
		return result;
	}
	
	public static FSIterator getFreeling2Iterator(JCas cas)
	{
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new Freeling2(cas)).getType());
		return  cas.createFilteredIterator(it, constraint);
	}
	
	public static FSIterator getSentenciaCompletitudIterator(JCas cas)
	{
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new SentenciaCompletitud(cas)).getType());
		return  cas.createFilteredIterator(it, constraint);
	}

	public static Collection<Freeling2> getFreeling2Annotations(JCas cas) 
	{
		FSIterator it = getFreeling2Iterator(cas);
		Collection<Freeling2> result = new ArrayList<Freeling2>();
		while (it.hasNext())
		{
			result.add((Freeling2) it.next());
		}
		return result;
	}

	public static Collection<SentenciaCompletitud> getSentenciasCompletitud(JCas cas) {
		FSIterator it = getSentenciaCompletitudIterator(cas);
		ArrayList<SentenciaCompletitud> result = new ArrayList<SentenciaCompletitud>();
		while (it.hasNext())
		{
			result.add((SentenciaCompletitud) it.next());
		}
		return result;
	}

	public static InfoDoc getInfoDoc(JCas cas) {
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add((new InfoDoc(cas)).getType());
		it = cas.createFilteredIterator(it, constraint);
		if (it.hasNext())
			return (InfoDoc) it.next();
		return null;
	}
	
	public static Resultado getResultado(JCas cas, Type resultadoType, Sentencia sentencia)
	{
		FSIterator it = cas.getAnnotationIndex().iterator();
		FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint();
		constraint.add(resultadoType);
		it = cas.createFilteredIterator(it, constraint);
		while (it.hasNext())
		{
			Resultado res = (Resultado)it.next();
			if (res.getBegin() == sentencia.getBegin())
				return res;
			if (res.getBegin() > sentencia.getBegin())
				return null;
		}
		return null;
	}

	public static double getPonderacionPorProfundidad(int profundidad) {
		switch (profundidad) {
		case 1:			
			return Constants.AlgoritmosConstants.PONDERACION_PROFUNDIDAD_1;
		case 2:			
			return Constants.AlgoritmosConstants.PONDERACION_PROFUNDIDAD_2;
		case 3:			
			return Constants.AlgoritmosConstants.PONDERACION_PROFUNDIDAD_3;
		case 4:			
			return Constants.AlgoritmosConstants.PONDERACION_PROFUNDIDAD_4;
		case 5:			
			return Constants.AlgoritmosConstants.PONDERACION_PROFUNDIDAD_5;
		case 6:			
			return Constants.AlgoritmosConstants.PONDERACION_PROFUNDIDAD_6;
		case 7:			
			return Constants.AlgoritmosConstants.PONDERACION_PROFUNDIDAD_7;	
		default:
			return Constants.AlgoritmosConstants.PONDERACION_PROFUNDIDAD_MAXIMA;
		}
	}

	public static void GenerarArchivoResultado(JCas cas) {
		StringBuffer sBuff = new StringBuffer();
		Collection<SentenciaCompletitud> sentenciasCompletitud = UtilidadesDeAnalisis.getSentenciasCompletitud(cas);
		String frase = UtilidadesDeAnalisis.getFrase(cas).getTexto();
		int cantRes1 = 0;
		int cantRes2 = 0;
		int cantRes3 = 0;
		for (SentenciaCompletitud sentenciaCompletitud : sentenciasCompletitud) {
			String sentenciaText = sentenciaCompletitud.getSentencia().getText();
			String beginSentence = "";
			String endSentence = "";
			boolean hayResultado1 = UtilidadesDeAnalisis.getResultado(cas, new Resultado1(cas).getType(), sentenciaCompletitud.getSentencia()) != null;
			boolean hayResultado2 = UtilidadesDeAnalisis.getResultado(cas, new Resultado2(cas).getType(), sentenciaCompletitud.getSentencia()) != null;
			boolean hayResultado3 = UtilidadesDeAnalisis.getResultado(cas, new Resultado3(cas).getType(), sentenciaCompletitud.getSentencia()) != null;
			if (hayResultado1)
			{
				beginSentence += "<R1>";
				endSentence += "</R1>";
				cantRes1++;
			}
			if (hayResultado2)
			{
				beginSentence += "<R2>";
				endSentence += "</R2>";
				cantRes2++;
			}
			if (hayResultado3)
			{
				beginSentence += "<R3>";
				endSentence += "</R3>";
				cantRes3++;
			}
			
			sBuff.append(beginSentence + sentenciaText + endSentence);
			
		}
		
		InfoDoc infoDocAnnotation = UtilidadesDeAnalisis.getInfoDoc(cas);
		sBuff.append("\r\n\r\n\r\n");
		sBuff.append("---------- INFORMACION DOCUMENTO -----------------");
		sBuff.append("\r\n");
		sBuff.append("\r\n");
		sBuff.append("CantOffsets:" +  infoDocAnnotation.getCantOffsets()+"\r\n");
		sBuff.append("CantPalabras:" +  infoDocAnnotation.getCantPalabras()+"\r\n");
		sBuff.append("CantPalabrasConOffset:" +  infoDocAnnotation.getCantPalabrasConOffset()+"\r\n");
		sBuff.append("CantSentencias:" +  infoDocAnnotation.getCantSentencias()+"\r\n");
		sBuff.append("CantSentenciasConOffset:" +  infoDocAnnotation.getCantSentenciasConOffset()+"\r\n");
		sBuff.append("\r\n");
		sBuff.append("Frase de consulta: " + frase);
		sBuff.append("\r\n");
		sBuff.append("CantTokensConsulta:" +  infoDocAnnotation.getCantTokensConsulta()+"\r\n");
		sBuff.append("CantTokensConsultaNoFiltered:" +  infoDocAnnotation.getCantTokensConsultaNoFiltered()+"\r\n");
		sBuff.append("CantOffsetsFraseConsulta:" +  infoDocAnnotation.getCantOffsetsFraseConsulta()+"\r\n");
		sBuff.append("\r\n");
		sBuff.append("CantNombresConsulta:" +  infoDocAnnotation.getCantNombresConsulta()+"\r\n");
		sBuff.append("CantVerbosConsulta:" +  infoDocAnnotation.getCantVerbosConsulta()+"\r\n");
		sBuff.append("CantAdjetivosConsulta:" +  infoDocAnnotation.getCantAdjetivosConsulta()+"\r\n");
		sBuff.append("CantAdverbiosConsulta:" +  infoDocAnnotation.getCantAdverbiosConsulta()+"\r\n");
		sBuff.append("CantNombresConsultaConOffset:" +  infoDocAnnotation.getCantNombresConsultaConOffset()+"\r\n");
		sBuff.append("CantVerbosConsultaConOffset:" +  infoDocAnnotation.getCantVerbosConsultaConOffset()+"\r\n");
		sBuff.append("CantAdjetivosConsultaConOffset:" +  infoDocAnnotation.getCantAdjetivosConsultaConOffset()+"\r\n");
		sBuff.append("CantAdverbiosConsultaConOffset:" +  infoDocAnnotation.getCantAdverbiosConsultaConOffset()+"\r\n");
		sBuff.append("\r\n");
		if (Constants.System.VENTANA_DE_DESAMBIGUACION && !Constants.IdentificadorConstants.USAR_TODOS_LOS_OFFSETS_DE_CONSULTA)
		{
			Collection<FreelingConsulta> freelingConColl = UtilidadesDeAnalisis.getFreelingConsultaAnnotators(cas);
			for (FreelingConsulta freelingConsulta : freelingConColl) {
				sBuff.append("Palabra: " + freelingConsulta.getWord() );
				if (freelingConsulta.getOffsets() != null && freelingConsulta.getOffsets().size() > 0)
					sBuff.append(" - Offset: " + freelingConsulta.getOffsets(0));
				sBuff.append("\r\n");
			}
			sBuff.append("\r\n");
		}
		sBuff.append("\r\n");
		sBuff.append("CantResultado1: " + cantRes1 +"\r\n");
		sBuff.append("CantResultado2: " + cantRes2 +"\r\n");
		sBuff.append("CantResultado3: " + cantRes3 +"\r\n");
		
		
		try {
			String tipoDesambiguacion = "AUTO";
			if (Constants.System.VENTANA_DE_DESAMBIGUACION && !Constants.IdentificadorConstants.USAR_TODOS_LOS_OFFSETS_DE_CONSULTA)
				tipoDesambiguacion = "MANUAL";
			else if (Constants.IdentificadorConstants.USAR_TODOS_LOS_OFFSETS_DE_CONSULTA)
				tipoDesambiguacion = "ALL";
			String fileName = Constants.System.RESULTADOS_DIR + frase + "_" + tipoDesambiguacion + "_" + (new Date()).getTime() +  ".doc";
			org.idtem.utils.FileUtils.createFile(fileName, sBuff.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	

}
